﻿
/********************************************************************************
** @ Date:2024/02/05
** @ Author: TangYanPing
** @ Description:日志控件
** @ Version:1.0.0
** @ ClassName:LogModule
** @ Fun:
********************************************************************************/

#ifndef LOGMODULE_H
#define LOGMODULE_H

#include <QWidget>
#include <QObject>
#include <QStandardItemModel>
#include <QMutex>
#include <QColor>
#include <QStyle>
#include <QtSql>
#include <QtXml>

#include <QWidgetAction>
#include <QPushButton>
#include <QLabel>
#include <QLineEdit>
#include <QComboBox>
#include <QCheckBox>
#include <QAction>
#include <QEvent>
#include <QTranslator>
#include <QTableView>

#ifdef LOGMODULE_LIBRARY
#  define LOGMODULESHARED_EXPORT Q_DECL_EXPORT
#else
#  define LOGMODULESHARED_EXPORT Q_DECL_IMPORT
#endif

//日志等级以及相关字体和图标路径
struct StLevelConfig
{
	quint16 nLogLevel;	//日志等级
	QString sDesc;		//描述
	QString sIconPath;	//图标路径
	QColor colorText;	//文字颜色
	QColor colorBack;	//背景颜色
	QIcon icon;			//图标图像
	bool bIsShowTable;	//是否界面表格显示
	bool bIsSaveLocal;	//是否本地保存
	bool bIsSaveDb;		//是否数据库保存
	bool bIsDebug;		//是否生成调试信息

	StLevelConfig()	//默认初始化
	{
		nLogLevel = 0;
		sDesc = QString();
		colorText = QColor(0x00, 0x00, 0x00);
		colorBack = QColor(0xFF, 0xFF, 0xFF);
		sIconPath = "";
		bIsShowTable = true;
		bIsSaveLocal = true;
		bIsSaveDb = true;
		bIsDebug = false;
	}
	StLevelConfig(int nLevel, QString desc, QColor text = QColor(0x00, 0x00, 0x00)
		, QColor back = QColor(0xFF, 0xFF, 0xFF), QIcon iconIn = QIcon(), QString sPath = ""
		, bool bShow = true, bool bLocal = true, bool bDb = false, bool bDebug = false)
	{
		nLogLevel = nLevel;
		sDesc = desc;
		colorText = text;
		colorBack = back;
		icon = iconIn;
		sIconPath = sPath;
		bIsShowTable = bShow;
		bIsSaveLocal = bLocal;
		bIsSaveDb = bDb;
		bIsDebug = bDebug;
	}
};

extern QMutex g_mutexLog;						//日志线程锁
class LogModulePrivate;
class CLogTabWidget;

class LOGMODULESHARED_EXPORT LogModule : public QWidget
{
    Q_OBJECT

public:
    /*****************************************
    描述：构造单个默认的日志控件
    *****************************************/
    LogModule(QWidget* parent = Q_NULLPTR);

    /*****************************************
    描述：构造单个默认的日志控件
    入参1：日志保存路径
    *****************************************/
    LogModule(QString sPath, QWidget* parent = Q_NULLPTR);

    /*****************************************
    描述：构造单个日志控件
    入参1：日志Tab页的标题，同时作为本地保存时产生文件的后缀
    入参2：日志保存路径
    *****************************************/
    LogModule(QString sTabName, QString sPath = QString(), QWidget* parent = Q_NULLPTR);

    /*****************************************
    描述：构造有多个Tab页日志控件
    入参1：
    int:Tab页的编号，发送日志时在AddMsg()第5位入参输入编号会将内容发向该编号的Tab页
    QString:Tab页的名称，作为该Tab的标题，同时作为本地保存时产生文件的后缀
    入参2：日志保存路径
	编号0默认为“系统日志”，如果想保留“系统日志”Tab，编号从1开始，如果不想保留，编号从0开始，会自动覆盖“系统日志”Tab
    *****************************************/
    LogModule(QMap<qint16, QString> mapTabInfo, QString sPath = QString(), QWidget* parent = Q_NULLPTR);

    ~LogModule();

	//返回值对应信息
	enum EReturn
	{
		enSuccess = 0,			//成功
		enInsNameExist = 1,		//新增tab页错误：名称已存在
		enInsNameVacant = 2,	//新增tab页错误：名称不能为空
		enInsNoInvalid = 3,		//新增tab页错误：编号无效 编号不能小于零
		enDelNoIsZero = 4,		//删除tab页错误：编号为0的页不能删除
		enDelNoNotExist = 5,	//删除tab页错误：对应编号不存在
		enDelNameNotExist = 6, 	//删除tab页错误：对应名称不存在
		enRtnNullptr = 7,		//返回tab页错误：空指针
		enRtnAlreadyExist = 8,	//返回tab页错误：原tab页已经返回成功
		enRtnTabNotExist = 9, 	//返回tab页错误：原tab页不存在
	};

	//日志等级枚举
	enum ELevel
	{
		enLvlRun = 1,		//运行
		enLvlInfo = 2,		//正常
		enLvlAlarm = 3,		//报警
		enLvlError = 4,		//错误
		enLvlHardWare = 5	//硬件故障
	};

public:
    /*****************************************
    描述：插入日志信息接口
    入参1 nLogLevel	：日志等级，与保存方式、显示字体颜色、背景色等相关
    入参2 sObject	：模块名
    入参3 sDesc		：日志内容正文
    入参4 sFl		：源代码行号，输出至本地日志文件，可为空
    入参5 nTabNo		：当前日志传进的表格tab编号，必须是已创建的tab，默认为0则进入系统日志页
    *****************************************/
    void AddMsg(qint16 nLogLevel, QString sObject, QString sDesc, QString sFl = "", qint16 nTabNo = 0);

	/*****************************************
	描述：插入日志信息接口
	入参1 nLogLevel	：日志等级，与保存方式、显示字体颜色、背景色等相关
	入参2 sObject	：模块名
	入参3 sDesc		：日志内容正文
	入参4 sFl		：源代码行号，输出至本地日志文件，可为空
	入参5 nTabNo		：当前日志传进的表格tab编号，必须是已创建的tab，默认为0则进入系统日志页
	*****************************************/
	void addMsg(qint16 nLogLevel, QString sObject, QString sDesc, QString sFl = "", qint16 nTabNo = 0);

    /*****************************************
    描述：传入操作人员姓名，存在不同权限用户登录操作时可用于区分操作者
    入参1：当前操作人员名称，存入数据库表的OPERATOR_NAME字段
    *****************************************/
    void setUserName(QString sUserName);

    /*****************************************
    描述：传入日志输入设备信息，多台设备运行并使用数据库时可用于区分日志源
    入参1：生成日志的设备信息，存入数据库表的DEV_INFO字段
    *****************************************/
    void setDevInfo(QString sDevInfo);

    /*****************************************
    描述：传入日志等级配置字典，可覆盖默认设置与本地设置
    入参1：日志等级对应字典
    *****************************************/
    void setLevelConfig(QMap<qint16, StLevelConfig> mapLevel);

    /*****************************************
    描述：返回当前日志控件的等级字典
    返回：当前设定的日志等级
    *****************************************/
    QMap<qint16,StLevelConfig> levelConfigs();

	/*****************************************
	描述：返回当前日志控件的等级名称字典
	返回：当前设定的日志等级全部名称
	*****************************************/
	QMap<qint16, QString> levelNames();

	/*****************************************
	描述：返回当前日志控件所有tab页的名称
	返回：当前设定的日志所有tab页名称
	*****************************************/
	QMap<qint16, QString> tabNames();

    /*****************************************
    描述：传入样式表覆盖原有设置
    入参1：QSS字符串
    *****************************************/
    void setQStyleSheet(QString sQss);

    /*****************************************
    描述：按编号切换当前的日志页
    入参1：日志页编号(非日志页序号，而是传入map的key)
    *****************************************/
    void setCurrentTab(qint16 nTabNo);

    /*****************************************
    描述：按名称切换当前日志页
    入参1：日志页名称
    *****************************************/
    void setCurrentTab(QString sTabName);

    /*****************************************
    描述：设定设置、历史查询、筛选等是否显示
    入参1：是否显示
    *****************************************/
    void setButtonShow(bool bShow);

	/*****************************************
	描述：按编号名称新增tab页，如已存在则覆盖该tab名称
	入参1：新增tab页编号
	入参2：新增tab页名称
	返回：错误参数
	备注：1.tab页顺序按照编号大小正序排列 2.编号不能小于0 名称不能为空
	*****************************************/
	int insertTab(qint16 nTabNo, QString sTabName);

	/*****************************************
	描述：按名称或编号移除tab页
	入参1：删除tab页编号/名称
	返回：错误参数
	备注：编号小于0的tab页不可删除 若以名称删除名称不能为空
	*****************************************/
	int removeTab(qint16 nTabNo);
	int removeTab(QString sTabName);

	/*****************************************
	描述：在末尾添加tab页
	入参1：新增tab页名称
	入参2：返回该tab的编号
	返回：错误参数
	备注：编号小于0的tab页不可删除 若以名称删除名称不能为空
	*****************************************/
	int appendTab(QString sTabName, qint32& nTabNo);

	/*****************************************
	描述：获取某一tab的表格指针
	入参：tab页编号
	返回：编号对应的tab页表格，如果不对应或找不到则返回空指针
	*****************************************/
	QTableView* getTab(qint16 nTabNo);

	/*****************************************
	描述：归还某一tab的表格指针
	入参：归还的tab页表格指针
	返回：错误参数
	备注：必须是从tab页中取出的表格，否则不兼容
	*****************************************/
	int returnTab(QTableView* pTable);

	/*****************************************
	描述：显示历史日志对话框
	*****************************************/
	void showHistoryDialog(QWidget* parent = Q_NULLPTR);

	/*****************************************
	描述：显示设置对话框
	*****************************************/
	void showConfigDialog(QWidget* parent = Q_NULLPTR);

private:
	/*****************************************
	描述：初始化页面
	*****************************************/
	void preInit();

private:
	CLogTabWidget* m_pLog;

	Q_DECLARE_PRIVATE(LogModule)
    Q_DISABLE_COPY(LogModule)
};

#endif // LOGMODULE_H
